package com.gzs.learn.admin;

import com.gzs.learn.admin.mapper.DbConfigMapper;
import com.gzs.learn.admin.truncate.TruncateService;
import com.gzs.learn.inf.GlobalConstant;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.internal.util.MockUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import redis.embedded.RedisServer;

import java.util.Map;

@ExtendWith(SpringExtension.class)
@ActiveProfiles(GlobalConstant.PROFILE_TEST_ENV)
@SpringBootTest(classes = WebApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
public class IntegrationBaseTest {
    private static RedisServer REDIS_SERVER = new RedisServer(TestConstants.REDIS_EMBEDDED_PORT);

    static {
        REDIS_SERVER.start();
    }

    @Autowired
    protected DbConfigMapper dbConfigMapper;

    @Autowired
    protected ApplicationContext context;

    @BeforeEach
    protected void setUp() {
        truncate();
        resetMocks();
    }

    private void truncate() {
        Map<String, TruncateService> truncateServiceMap = context.getBeansOfType(TruncateService.class);
        for (Map.Entry<String, TruncateService> entry : truncateServiceMap.entrySet()) {
            String key = entry.getKey();
            TruncateService service = entry.getValue();
            try {
                service.truncate();
            } catch (Exception e) {
                log.error("truncate key {} do truncate resources error", key, e);
            }
        }
    }

    private void resetMocks() {
        for (String name : context.getBeanDefinitionNames()) {
            try {
                Object bean = context.getBean(name);
                if (MockUtil.isMock(bean)) {
                    Mockito.reset(bean);
                }
            } catch (Exception e) {
                log.error("reset mockbean {} error", name, e);
            }
        }
    }
}
